﻿// Copyright (C) 2012 Kim Jensen, TaskJunction.com
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TaskJunctionLib.Model;
using TaskJunctionLib.Mapping;
using TaskJunctionLib.Communication;

namespace TaskJunctionLib.Repository
{
    public abstract class CachableRepository<T, TMapper> : Repository<T, TMapper>
        where T : ModelEntity
        where TMapper : IObjectMapper<T>, new()
    {

        public bool UseCaching
        {
            get { return useCaching; }
            set { 
                useCaching = value;
                Cache = null;
            }
        }
        private bool useCaching = true;

        protected override IList<T> _LoadList(string resourceName)
        {
            if (!UseCaching)
                return base._LoadList(resourceName);
            lock (thisLock)
            {
                Cache = Cache ?? base._LoadList(resourceName);
                return Cache;
            }
        }

        public override T Load(int id)
        {
            return _LoadList(GetResourceName()).FirstOrDefault(x => x.Id == id) ?? base.Load(id);
        }

        public override void Delete(T obj)
        {
            ClearCache();
            base.Delete(obj);
        }

        public override void Save(T obj)
        {
            ClearCache();
            base.Save(obj);
        }

        public virtual void ClearCache()
        {
            lock (thisLock)
            {
                Cache = null;
            }
        }

        protected IList<T> Cache
        {
            get
            {
                return (useCaching) ? Client.GetObjectCache<T>() : null;
            }
            set
            {
                if (useCaching)
                {
                    Client.SetObjectCache<T>(value);
                }
            }
        }

        protected Object thisLock = new Object();
    }
}
